<?php

namespace serv\queue\system;

use GuzzleHttp\Client;
use of;
use L;

class Currency
{
    const CREATED_BY = 'sys_pos_currency';
    const DEFAULT_PRIORITY = 99;
    const STATUS_ACTIVE = 1;

    // 同步当天最新汇率信息
    public static function syncRate($arr)
    {
        $arr = $arr['data'];
        if (empty($arr)) {
            return true;
        }
        try {
            $url = of::config('env.CURRENCY_URL');
            $result = self::fetchRates($url);

            $today = date('Y-m-d');
            $lastDayOfMonth = date('Y-m-t');
            $isUpdateDay = self::isUpdateDay($today, $lastDayOfMonth);
            $nextMonth = self::getNextMonthDate($today, $lastDayOfMonth);
            if (2 == $arr['status']) {
                $isUpdateDay = true;
            }
            if (isset($result['records']) && !empty($result['records']) && $isUpdateDay) {
                $data = self::prepareData($result['records'], $nextMonth, $result['data']['lastDate']);
                self::updateDatabase($data);
            } else {
                of::work(401, '获取汇率失败');
            }
        } catch (\Exception $e) {
            of::work(500, '同步汇率信息时发生错误: ' . $e->getMessage());
        }

        return true;
    }

    // 从指定URL获取汇率数据
    private static function fetchRates($url)
    {
        $client = new Client();
        $response = $client->get($url);
        return json_decode($response->getBody(), true);
    }

    // 判断当天是否是月初或月末
    private static function isUpdateDay($today, $lastDayOfMonth)
    {
        return $today === date('Y-m-01') || $today === $lastDayOfMonth || $today === date('Y-m-d', strtotime('+1 day'));
    }

    // 如果当天是月末，则获取第二个月的第一天，否则就是当月的1号
    private static function getNextMonthDate($today, $lastDayOfMonth)
    {
        return $today === $lastDayOfMonth ? date('Y-m-01', strtotime('+1 month')) : date('Y-m-01');
    }

    // 准备要插入或更新到数据库的数据
    private static function prepareData($records, $nextMonth, $lastUpdateDate)
    {
        $data = [];
        foreach ($records as $record) {
            if (preg_match('/^CNY/i', $record['vrtEName'])) {
                $value = round(1 / $record['price'], 4);
                $data[] = self::createDataEntry((explode("/", $record['vrtName']))[1], $record, $value, $nextMonth, $lastUpdateDate);
            } else {
                list($name, $value) = self::calculateValue($record);
                $data[] = self::createDataEntry($name, $record, $value, $nextMonth, $lastUpdateDate);
            }
        }
        return $data;
    }

    // 计算汇率的值
    private static function calculateValue($record)
    {
        if (preg_match('/^100JPY/i', $record['vrtEName'])) {
            $name = "日元";
            $value = round($record['price'] / 100, 4);
        } else {
            $name = (explode("/", $record['vrtName']))[0];
            $value = round($record['price'], 4);
        }
        return [
            $name,
            $value
        ];
    }

    // 创建一个数据库条目
    private static function createDataEntry($name, $record, $value, $nextMonth, $lastUpdateDate)
    {
        return [
            'name' => $name,
            'code' => $record['foreignCName'],
            'symbol' => self::symbol($record['foreignCName']),
            'date' => $nextMonth,
            'value' => $value,
            'rate' => $value,
            'created_by' => self::CREATED_BY,
            'created_at' => date('Y-m-d H:i:s'),
            'updated_by' => self::CREATED_BY,
            'updated_at' => date('Y-m-d H:i:s', strtotime($lastUpdateDate)),
            'status' => self::STATUS_ACTIVE,
            'priority' => self::DEFAULT_PRIORITY,
        ];
    }

    // 更新数据库中的数据
    private static function updateDatabase($data)
    {
        foreach ($data as $entry) {
            $sql = "INSERT INTO currency(" . implode(",", array_keys($entry)) . ") VALUES 
                    ('" . implode("','", array_values($entry)) . "') 
                    ON DUPLICATE KEY UPDATE 
                        value = '{$entry['value']}',
                        rate = '{$entry['value']}',
                        symbol = '{$entry['symbol']}',
                        status = '{$entry['status']}',
                        priority = '{$entry['priority']}',
                        updated_by = '{$entry['updated_by']}',
                        updated_at = '{$entry['updated_at']}';";
            L::sql($sql);
        }
    }

    // 根据货币代码获取货币符号
    private static function symbol($currency)
    {
        $symbols = [
            'USD' => '$',
            'EUR' => '€',
            'JPY' => '￥',
            'HKD' => '$',
            'GBP' => '￡',
            'AUD' => '$',
            'NZD' => '$',
            'SGD' => '$',
            'CHF' => '₣',
            'CAD' => '$',
            'MYR' => '$',
            'RUB' => 'руб',
            'ZAR' => 'R',
            'KRW' => '₩',
            'AED' => 'AED',
            'SAR' => 'SAR',
            'HUF' => 'Ft',
            'PLN' => 'zł',
            'DKK' => 'kr',
            'SEK' => 'kr',
            'NOK' => 'kr',
            'TRY' => '₺',
            'MXN' => '$',
            'THB' => '฿',
            'MOP' => 'MOP$'
        ];
        return $symbols[$currency] ?? '';
    }
}